﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Windows.Forms;

namespace RedRiver.Framework.XtraCommon.FormHelper{
    /// <summary>
    /// 数据集 助手
    /// </summary>
    public static class DataSetHelper{
        #region SqlParameter To RowFilter

        /// <summary>
        /// SqlParameter 到 RowFilter字符串转换
        /// </summary>
        /// <param name="paras"></param>
        /// <returns></returns>
        private static string SqlParametersToRowFilter(IList<SqlParameter> paras){
            if (paras.Count == 0){
                return string.Empty;
            }
            var filters = new string[paras.Count];
            for (int i = 0; i < paras.Count; i++){
                switch (paras[i].SqlDbType){
                    case SqlDbType.BigInt:
                    case SqlDbType.Bit:
                    case SqlDbType.Decimal:
                    case SqlDbType.Float:
                    case SqlDbType.Int:
                    case SqlDbType.Money:
                    case SqlDbType.Real:
                    case SqlDbType.SmallMoney:
                    case SqlDbType.TinyInt:
                        filters[i] = paras[i].SourceColumn + "=" + paras[i].Value;
                        break;
                    case SqlDbType.UniqueIdentifier:
                    case SqlDbType.Char:
                    case SqlDbType.DateTime:
                    case SqlDbType.NChar:
                    case SqlDbType.NVarChar:
                    case SqlDbType.VarChar:
                        filters[i] = paras[i].SourceColumn + "='" + paras[i].Value + "'";
                        break;
                }
            }
            return string.Join(" AND ", filters);
        }

        /// <summary>
        /// SqlParameter 到 RowFilter字符串转换
        /// 如果和表的列进行比对,如果参数中的 SourceColumn 在表中不存在,则过滤掉
        /// 如果没有匹配的参数,返回 string.Empty
        /// </summary>
        /// <param name="table"></param>
        /// <param name="paras"></param>
        /// <returns></returns>
        public static string SqlParametersToRowFilter(DataTable table, SqlParameter[] paras){
            var result = new List<SqlParameter>();
            foreach (SqlParameter para in paras){
                if (string.IsNullOrEmpty(para.SourceColumn)){
                    string paraName = para.ParameterName.Replace("@", string.Empty);
                    if (table.Columns.Contains(paraName)){
                        para.SourceColumn = paraName;
                        result.Add(para);
                    }
                } else if (table.Columns.Contains(para.SourceColumn)){
                    result.Add(para);
                }
            }
            return SqlParametersToRowFilter(result);
        }

        public static DataSet FilterDataSet(this DataSet dataSet, params SqlParameter[] paras){
            DataSet filted = dataSet.Clone();
            filted.EnforceConstraints = false;
            foreach (DataTable table in dataSet.Tables){
                string rowFilter = SqlParametersToRowFilter(table, paras);
                if (rowFilter == string.Empty){
                    dataSet.Merge(table);
                } else{
                    dataSet.Merge(table.Select(rowFilter));
                }
            }
            filted.EnforceConstraints = true;
            return filted;
        }

        #endregion

        #region MergeData

        /// <summary>
        /// 合并数据
        /// </summary>
        /// <param name="sourceData"></param>
        /// <param name="rows"></param>
        public static void MergeData(this DataSet sourceData, params DataRow[] rows){
            sourceData.Merge(rows);
            foreach (DataRow row in rows){
                foreach (DataRelation childRelation in row.Table.ChildRelations){
                    MergeData(sourceData, row.GetChildRows(childRelation));
                }
            }
        }

        /// <summary>
        /// 合并数据
        /// </summary>
        /// <param name="sourceData"></param>
        /// <param name="tables"></param>
        public static void MergeData(this DataSet sourceData, params DataTable[] tables){
            foreach (DataTable table in tables){
                sourceData.Merge(table);
                foreach (DataRelation childRelation in table.ChildRelations){
                    MergeData(sourceData, childRelation.ChildTable);
                }
            }
        }

        /// <summary>
        /// 合并数据
        /// </summary>
        /// <param name="dataSource"></param>
        /// <param name="mergedData"></param>
        public static void MergeData(object dataSource, object mergedData){
            if (dataSource == null){
                throw new ArgumentNullException("dataSource");
            }
            if (dataSource is DataSet){
                MergeData((DataSet) dataSource, mergedData);
            } else if (dataSource is BindingSource){
                MergeData(((BindingSource) dataSource).DataSource, mergedData);
            } else if (dataSource is DataView){
                MergeData(((DataView) dataSource).Table.DataSet, mergedData);
            } else if (dataSource is DataTable){
                MergeData(((DataTable) dataSource).DataSet, mergedData);
            } else if (dataSource is DataRow){
                MergeData(((DataRow) dataSource).Table.DataSet, mergedData);
            } else if (dataSource is DataRowView){
                MergeData(((DataRowView) dataSource).Row.Table.DataSet, mergedData);
            } else{
                throw new NotSupportedException("不支持的数据源类型,dataSource:" + dataSource.GetType().Name);
            }
        }

        public static void MergeData(this DataTable dataTable, object mergedData) {
            if (dataTable == null) {
                throw new ArgumentNullException("dataTable");
            }
            if (mergedData is DataSet) {
                dataTable.Merge(((DataSet)mergedData).Tables[dataTable.TableName]);
            } else if (mergedData is DataTable) {
                dataTable.Merge((DataTable)mergedData);
            } else if (mergedData is DataView) {
                dataTable.Merge(((DataView)mergedData).Table);
            } else if(dataTable.DataSet!=null){
                MergeData(dataTable.DataSet,mergedData);
            }
        }

        /// <summary>
        /// 合并数据
        /// </summary>
        /// <param name="dataSource"></param>
        /// <param name="mergedData"></param>
        public static void MergeData(this DataSet dataSource, object mergedData){
            if(dataSource == null){
                throw new ArgumentNullException("dataSource");
            }
            if (mergedData is DataSet){
                dataSource.Merge((DataSet) mergedData);
            } else if (mergedData is DataRowView){
                MergeData(dataSource, ((DataRowView) mergedData).Row);
            } else if (mergedData is DataRow){
                MergeData(dataSource, (DataRow) mergedData);
            } else if (mergedData is DataTable){
                MergeData(dataSource, (DataTable) mergedData);
            } else if (mergedData is DataView){
                MergeData(dataSource, ((DataView) mergedData).Table);
            } else{
                throw new NotSupportedException("不支持的合并数据类型,mergedData:" + mergedData.GetType().Name);
            }
        }

        #endregion MergeData
    }
}